from flask import Blueprint, jsonify, g, request, current_app
from sqlalchemy.exc import DataError

from models import Order, OrderProduct, Product, Cart, db
from sqlalchemy import desc
from datetime import datetime, timedelta

api_bp = Blueprint('order', __name__)


# 1. 创建订单接口
@api_bp.route('/orders', methods=['POST'])
def create_order():
    try:
        user_id = g.current_user.get('id')
        if not user_id:
            return jsonify({"message": "用户未登录"}), 401

        # 获取请求参数
        data = request.json
        cart_ids = data.get('cart_ids')  # 购物车项ID列表

        # 新增：获取地址信息
        recipient_name = data.get('recipient_name')
        recipient_phone = data.get('recipient_phone')
        shipping_address = data.get('shipping_address')

        # 获取订单金额信息
        subtotal = data.get('subtotal')
        total_amount = data.get('total_amount')
        shipping_fee = data.get('shipping_fee', 0.0)
        coupon_discount = data.get('coupon_discount', 0.0)

        # 校验必填参数
        if not cart_ids or not recipient_name or not recipient_phone or not shipping_address:
            return jsonify({"message": "缺少购物车商品信息或地址信息"}), 400

        if subtotal is None:
            return jsonify({"message": "缺少订单商品总价信息"}), 400

        if total_amount is None:
            return jsonify({"message": "缺少订单总金额信息"}), 400

        # 获取购物车中的商品信息
        cart_items = Cart.query.filter(Cart.id.in_(cart_ids), Cart.user_id == user_id).all()
        if not cart_items:
            return jsonify({"message": "购物车商品不存在"}), 404

        # 创建订单主记录（直接保存地址信息）
        order = Order(
            user_id=user_id,
            recipient_name=recipient_name,
            recipient_phone=recipient_phone,
            shipping_address=shipping_address,
            order_number=f"ORD-{datetime.now().strftime('%Y%m%d%H%M%S')}-{user_id}",
            subtotal=subtotal,
            total_amount=total_amount,
            shipping_fee=shipping_fee,
            coupon_discount=coupon_discount,
            order_status='待支付',
        )
        db.session.add(order)
        db.session.flush()  # 获取新创建的订单ID

        # 生成订单商品关联表记录
        order_products = []
        for cart_item in cart_items:
            product = Product.query.get(cart_item.product_id)
            if not product:
                raise Exception(f"商品ID {cart_item.product_id} 不存在")

            quantity = cart_item.quantity
            subtotal = product.price * quantity

            # 创建订单商品关联记录，包含订单ID和商品ID
            order_product = OrderProduct(
                order_id=order.id,  # 关联到新创建的订单
                product_id=product.id,
                quantity=quantity,
                price=product.price,
                subtotal=subtotal
            )
            order_products.append(order_product)

        # 添加所有订单商品关联记录
        db.session.add_all(order_products)
        db.session.commit()

        # 清空已下单的购物车项（确保使用正确的cart_ids）
        Cart.query.filter(Cart.id.in_(cart_ids), Cart.user_id == user_id).delete(synchronize_session=False)
        db.session.commit()

        return jsonify({
            "message": "订单创建成功",
            "order_id": order.id,
        }), 201

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建订单失败: {str(e)}", exc_info=True)
        return jsonify({"message": "订单创建失败"}), 500


# 2. 获取用户订单列表（支持分页和筛选）
@api_bp.route('/orders', methods=['GET'])
def get_user_orders():
    try:
        user_id = g.current_user.get('id')
        if not user_id:
            return jsonify({"message": "用户未登录"}), 401

        # 分页参数
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('page_size', 10, type=int)
        page_size = min(max(page_size, 1), 100)

        # 筛选参数（默认为None，表示不筛选）
        order_number = request.args.get('order_number')
        time_range = request.args.get('time_range')  # 可选值: one_month, three_months, six_months
        status = request.args.get('status')  # 可选值: 待支付、待发货、待收货、已完成

        # 构建查询对象
        query = Order.query.filter_by(user_id=user_id)

        # 添加订单号筛选
        if order_number:
            query = query.filter(Order.order_number.like(f'%{order_number}%'))

        # 添加时间范围筛选
        if time_range:
            now = datetime.now()
            if time_range == 'one_month':
                start_date = now - timedelta(days=30)
                query = query.filter(Order.created_at >= start_date)
            elif time_range == 'three_months':
                start_date = now - timedelta(days=90)
                query = query.filter(Order.created_at >= start_date)
            elif time_range == 'six_months':
                start_date = now - timedelta(days=180)
                query = query.filter(Order.created_at >= start_date)


        # 添加订单状态筛选
        if status:
            if status == '待支付':
                query = query.filter(Order.order_status == status)
            elif status == '待发货':
                query = query.filter(Order.order_status == status)
            elif status == '待收货':
                query = query.filter(Order.order_status == status)
            elif status == '已完成':
                query = query.filter(Order.order_status == status)

        # 按创建时间倒序排列
        query = query.order_by(desc(Order.created_at))

        total_items = query.count()
        total_pages = (total_items + page_size - 1) // page_size
        page = max(1, min(page, total_pages))

        orders = query.offset((page - 1) * page_size).limit(page_size).all()

        # 格式化订单数据
        data = []
        for order in orders:
            # 获取订单商品信息
            order_products = []
            for op in order.order_products:
                product_info = {
                    "id": op.product_id,
                    "name": op.product.name,
                    "quantity": op.quantity,
                    "price": float(op.price),
                    "subtotal": float(op.subtotal),
                    "image": op.product.image if hasattr(op.product, 'image') else None
                }
                order_products.append(product_info)

            data.append({
                "order_id": order.id,
                "order_number": order.order_number,
                "total_amount": float(order.total_amount),
                "order_status": order.order_status,
                "created_at": order.created_at.strftime("%Y-%m-%d %H:%M:%S"),
                "address": {
                    "recipient_name": order.recipient_name,
                    "recipient_phone": order.recipient_phone,
                    "shipping_address": order.shipping_address
                },
                "products": order_products
            })

        return jsonify({
            "message": "获取订单列表成功",
            "data": data,
            "pagination": {
                "current_page": page,
                "page_size": page_size,
                "total_pages": total_pages,
                "total_items": total_items
            }
        }), 200

    except Exception as e:
        current_app.logger.error(f"获取订单列表失败: {str(e)}", exc_info=True)
        return jsonify({"message": "获取订单列表失败"}), 500
# 3. 获取订单详情
@api_bp.route('/orders/<int:order_id>', methods=['GET'])
def get_order_detail(order_id):
    try:
        user_id = g.current_user.get('id')
        if not user_id:
            return jsonify({"message": "用户未登录"}), 401

        # 校验订单归属权
        order = Order.query.filter_by(id=order_id, user_id=user_id).first()
        if not order:
            return jsonify({"message": "订单不存在或无权限访问"}), 404

        # 计算优惠券优惠金额（根据订单总金额和商品小计总和计算）
        product_total = sum(op.subtotal for op in order.order_products)
        coupon_discount = float(product_total - order.total_amount) if product_total > order.total_amount else 0.0

        # 组装订单详情（包含商品明细和地址信息）
        order_detail = {
            "order_id": order.id,
            "order_number": order.order_number,
            "subtotal": float(order.subtotal),
            "total_amount": float(order.total_amount),
            "shipping_fee": float(order.shipping_fee),  # 新增：返回运费
            "coupon_discount": coupon_discount,  # 新增：返回优惠券优惠金额
            "order_status": order.order_status,
            "created_at": order.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "payment_method": order.payment_method,  # 新增：返回支付方式
            "payment_time": order.payment_time.strftime("%Y-%m-%d %H:%M:%S") if order.payment_time else None,
            "transaction_id": order.transaction_id,
            "address": {
                "recipient_name": order.recipient_name,
                "recipient_phone": order.recipient_phone,
                "shipping_address": order.shipping_address
            },
            "products": []
        }

        # 添加商品明细
        for op in order.order_products:
            order_detail["products"].append({
                "id": op.product_id,
                "name": op.product.name,  # 假设OrderProduct通过backref关联Product
                "quantity": op.quantity,
                "price": float(op.price),
                "subtotal": float(op.subtotal),
                "image": op.product.image if hasattr(op.product, 'image') else None  # 新增：返回商品图片
            })

        return jsonify({
            "message": "获取订单详情成功",
            "data": order_detail
        }), 200

    except Exception as e:
        current_app.logger.error(f"获取订单详情失败: {str(e)}", exc_info=True)
        return jsonify({"message": "获取订单详情失败"}), 500


# 4. 取消订单接口
@api_bp.route('/orders/<int:order_id>', methods=['DELETE'])
def cancel_order(order_id):
    try:
        user_id = g.current_user.get('id')
        if not user_id:
            return jsonify({"message": "用户未登录"}), 401

        # 校验订单状态（仅允许取消待支付订单）
        order = Order.query.filter_by(
            id=order_id,
            user_id=user_id,
            order_status='待支付'
        ).first()
        if not order:
            return jsonify({"message": "订单不存在或状态不可取消"}), 404

        # 更新订单状态为已取消
        order.order_status = '已取消'
        db.session.commit()

        return jsonify({"message": "订单取消成功"}), 200

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"取消订单失败: {str(e)}", exc_info=True)
        return jsonify({"message": "订单取消失败"}), 500


# 5. 订单支付接口
@api_bp.route('/orders/<int:order_id>/pay', methods=['POST'])
def pay_order(order_id):
    try:
        user_id = g.current_user.get('id')
        if not user_id:
            return jsonify({"message": "用户未登录"}), 401

        # 获取支付方式
        data = request.json
        payment_method = data.get('payment_method')

        if not payment_method:
            return jsonify({"message": "缺少支付方式"}), 400

        # 映射前端支付方式到数据库枚举值
        payment_method_mapping = {
            'wechat': '微信支付',
            'alipay': '支付宝',  # 需确认数据库枚举中是否有"支付宝"
            'card': '银行卡支付',
            'apple': '苹果支付'
        }

        if payment_method not in payment_method_mapping:
            return jsonify({"message": "不支持的支付方式"}), 400

        # 校验订单状态（仅允许支付待支付订单）
        order = Order.query.filter_by(
            id=order_id,
            user_id=user_id,
            order_status='待支付'
        ).first()

        if not order:
            return jsonify({"message": "订单不存在或状态不可支付"}), 404

        # 生成支付交易号
        transaction_id = f"PAY-{datetime.now().strftime('%Y%m%d%H%M%S')}-{order_id}"

        # 更新订单状态和支付信息
        order.order_status = '已支付'  # 这里会导致问题，需要映射到枚举值
        order.payment_method = payment_method_mapping[payment_method]
        order.payment_time = datetime.now()
        order.transaction_id = transaction_id

        db.session.commit()

        return jsonify({
            "message": "支付成功",
            "order_id": order_id,
            "transaction_id": transaction_id,
            "payment_method": payment_method,  # 返回前端使用的支付方式标识
            "payment_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }), 200

    except DataError as e:
        db.session.rollback()
        current_app.logger.error(f"枚举值不匹配: {str(e)}", exc_info=True)
        return jsonify({"message": "订单状态或支付方式错误，请联系管理员"}), 500

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"支付失败: {str(e)}", exc_info=True)
        return jsonify({"message": "支付处理失败"}), 500